package com.sequoiadb.demo;

import com.sequoiadb.base.*;
import org.bson.BSONObject;
import org.springframework.beans.factory.annotation.Value;

import javax.annotation.Resource;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
import java.util.ArrayList;
import java.util.List;

/**
 * Created by gaoshengjie on 2015/7/3.
 */

public abstract class BaseDAO<T> {
    @Resource
    private SequoiadbDatasource datasource;

    @Value("default")
    private String collectionSpace;

    public String getCollectionSpace() {
        return collectionSpace;
    }

    public void setCollectionSpace(String collectionSpace) {
        this.collectionSpace = collectionSpace;
    }

    public SequoiadbDatasource getDatasource() {
        return datasource;
    }

    public void setDatasource(SequoiadbDatasource datasource) {
        this.datasource = datasource;
    }

    public  List<T> query(BSONObject select, BSONObject where, BSONObject orderby,BSONObject hint,Page page){
        List<T> list=new ArrayList<T>();
        Sequoiadb sequoiadb=null;
        try {
            sequoiadb=getDatasource().getConnection();
            DBCollection dbCollection=getDBCollection(sequoiadb);
            DBCursor dbCursor=dbCollection.query(where, select, orderby, hint, page.getCurrent() * page.getStep(), page.getStep());
            while(dbCursor.hasNext()){
                list.add((T) dbCursor.getNext().as(getGenericClass()));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(sequoiadb != null){
                getDatasource().close(sequoiadb);
            }
        }
        return list;
    }
    public   T findOne(BSONObject select,BSONObject where){
        T t=null;
        Sequoiadb sequoiadb=null;
        try {
            sequoiadb=getDatasource().getConnection();
            DBCollection dbCollection=getDBCollection(sequoiadb);
            t= (T) dbCollection.queryOne(where, select,null,null, 0).as(getGenericClass());
        } catch (Exception e) {
            e.printStackTrace();
        }finally {
            if(sequoiadb != null){
                getDatasource().close(sequoiadb);
            }
        }
        return t;
    }
    public   boolean delete(BSONObject where){
        Sequoiadb sequoiadb=null;
        try {
            sequoiadb=getDatasource().getConnection();
            DBCollection dbCollection=getDBCollection(sequoiadb);
            dbCollection.delete(where);
            return true;
        } catch (Exception e) {
            return false;
        }finally {
            if(sequoiadb != null){
                getDatasource().close(sequoiadb);
            }
        }
    }
    public   boolean update(BSONObject modify,BSONObject where){
        Sequoiadb sequoiadb=null;
        try {
            sequoiadb=getDatasource().getConnection();
            DBCollection dbCollection=getDBCollection(sequoiadb);
            dbCollection.update(where,modify,null);
            return true;
        } catch (Exception e) {
            return false;
        }finally {
            if(sequoiadb != null){
                getDatasource().close(sequoiadb);
            }
        }
    }

    public DBCollection getDBCollection(Sequoiadb sequoiadb){
        CollectionSpace space=sequoiadb.getCollectionSpace(collectionSpace);
        return space.getCollection(getDBCollectionName());
    }

    public String getDBCollectionName(){
        Class clazz = getGenericClass();
        return clazz.getSimpleName().toLowerCase();
    }

    public Class getGenericClass(){
        Type genType = this.getClass().getGenericSuperclass();
        Type[] params = ((ParameterizedType) genType).getActualTypeArguments();
        Class clazz = (Class<T>) params[0];
        return clazz;
    }
}
